/* ============================================================================== 
2  * NET Framework：4.0.30319.18408
3  * 创 建 者：$projectname$.qd01.zhouwei 
4  * 创建日期：2014/10/16 14:15:11  
5  * 功能说明：
6  * 引用说明：
* ==============================================================================*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
namespace TEmit
{
   

    /// <summary>

    /// 使用类的属性的Description属性对应DataTable中的字段名

    /// </summary>

    public static class TableToModel
    {

        /// <summary>

        /// 将DataRow类型转化为指定类型的实体

        /// </summary>

        /// <typeparam name="T">实体类型</typeparam>

        /// <returns></returns>

        public static T ToModel<T>(this DataRow dr) where T : class, new()
        {

            return ToModel<T>(dr, true);

        }

        /// <summary>

        /// 将DataRow类型转化为指定类型的实体

        /// </summary>

        /// <typeparam name="T">实体类型</typeparam>

        /// <param name="dateTimeToString">是否需要将日期转换为字符串，默认为转换,值为true</param>

        /// <returns></returns>

        /// <summary>

        public static T ToModel<T>(this DataRow dr, bool dateTimeToString) where T : class, new()
        {

            if (dr != null)

                return ToList<T>(dr.Table, dateTimeToString).First();



            return null;

        }



        /// <summary>

        ///将DataTable类型转化为指定类型的实体集合

        /// </summary>

        /// <typeparam name="T">实体类型</typeparam>

        /// <returns></returns>

        public static List<T> ToList<T>(this DataTable dt) where T : class, new()
        {

            return ToList<T>(dt, true);

        }



        /// <summary>

        /// 将DataTable类型转化为指定类型的实体集合

        /// </summary>

        /// <typeparam name="T">实体类型</typeparam>

        /// <param name="dateTimeToString">是否需要将日期转换为字符串，默认为转换,值为true</param>

        /// <returns></returns>

        public static List<T> ToList<T>(this DataTable dt, bool dateTimeToString) where T : class, new()
        {

            List<T> list = new List<T>();



            if (dt != null)
            {

                List<PropertyInfo> infos = new List<PropertyInfo>();



                Array.ForEach<PropertyInfo>(typeof(T).GetProperties(), p =>
                {

                    foreach (Attribute att in p.GetCustomAttributes(true))
                    {

                        System.ComponentModel.DescriptionAttribute dscript = att as System.ComponentModel.DescriptionAttribute;

                        if (dscript != null)
                        {

                            if (dt.Columns.Contains(dscript.Description) == true)
                            {

                                infos.Add(p);

                            }

                        }

                    }



                });



                SetList<T>(list, infos, dt, dateTimeToString);

            }



            return list;

        }



        #region 私有方法



        private static void SetList<T>(List<T> list, List<PropertyInfo> infos, DataTable dt, bool dateTimeToString) where T : class, new()
        {

            foreach (DataRow dr in dt.Rows)
            {

                T model = new T();



                infos.ForEach(p =>
                {

                    foreach (Attribute att in p.GetCustomAttributes(true))
                    {

                        System.ComponentModel.DescriptionAttribute dscript = att as System.ComponentModel.DescriptionAttribute;

                        if (dscript != null)
                        {

                            if (dr[dscript.Description] != DBNull.Value)
                            {

                                object tempValue = dr[dscript.Description];

                                if (dr[dscript.Description].GetType() == typeof(DateTime) && dateTimeToString == true)
                                {

                                    tempValue = dr[p.Name].ToString();

                                }

                                try
                                {

                                    p.SetValue(model, tempValue, null);

                                }

                                catch { }

                            }

                        }

                    }

                });

                list.Add(model);

            }

        }



        #endregion

    }

}

